package com.michale.admin.controller.permissions;

import com.github.pagehelper.PageInfo;
import com.michale.admin.controller.tool.BaseController;
import com.michale.common.annotation.Log;
import com.michale.common.constants.UserConstant;
import com.michale.common.domain.permissions.RoleEntity;
import com.michale.common.domain.permissions.UserEntity;
import com.michale.common.domain.system.DeptEntity;
import com.michale.common.enmus.BusinessType;
import com.michale.common.result.AjaxResult;
import com.michale.common.result.PageResult;
import com.michale.common.utils.String.StringUtils;
import com.michale.common.utils.security.SecurityUtils;
import com.michale.system.service.DeptService;
import com.michale.system.service.PostService;
import com.michale.system.service.RoleService;
import com.michale.system.service.UserService;
import com.michale.system.vo.user.UserInfoVo;
import io.swagger.annotations.Api;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.List;
import java.util.stream.Collectors;


/**
 * @author Michale
 * @apiNote 用户管理
 */
@Api(tags = "用户管理")
@RestController
@RequestMapping("permissions/user")
public class UserController extends BaseController {

    @Resource
    private UserService userService;
    @Resource
    private DeptService deptService;
    @Resource
    private PostService postService;
    @Resource
    private RoleService roleService;

    /**
     * 获取用户列表
     *
     * @param userEntity 查询参数
     * @return 用户列表
     */
    @GetMapping("/userList")
    @PreAuthorize("@security.isPermission('permissions:user:list')")
    public PageResult getUserList(UserEntity userEntity) {
        startPage();
        List<UserEntity> userList = userService.selectUserList(userEntity);
        PageInfo<UserEntity> pageInfo = new PageInfo<>(userList);
        return pageResult(pageInfo);
    }

    /**
     * 新增用户
     *
     * @param userEntity 用户信息
     * @return 结果
     */
    @PostMapping("/insertUser")
    @Log(title = "用户管理", businessType = BusinessType.INSERT)
    @PreAuthorize("@security.isPermission('permissions:user:add')")
    public AjaxResult insertUser(@Validated @RequestBody UserEntity userEntity) {
        if (UserConstant.NOT_UNIQUE.equals(userService.checkUserNameUnique(userEntity))) {
            return error("新增用户'" + userEntity.getUserName() + "'失败，登录账号已存在");
        } else if (StringUtils.isNotEmpty(userEntity.getPhoneNumber())
                && UserConstant.NOT_UNIQUE.equals(userService.checkPhoneUnique(userEntity))) {
            return error("新增用户'" + userEntity.getUserName() + "'失败，手机号码已存在");
        } else if (StringUtils.isNotEmpty(userEntity.getEmail())
                && UserConstant.NOT_UNIQUE.equals(userService.checkEmailUnique(userEntity))) {
            return error("新增用户'" + userEntity.getUserName() + "'失败，邮箱账号已存在");
        }
        return toAjax(userService.insertUser(userEntity));
    }

    /**
     * 根据用户ID获取详细信息
     *
     * @param userId 用户ID
     * @return 用户信息
     */
    @GetMapping(value = {"/", "/{userId}"})
    @PreAuthorize("@security.isPermission('permissions:user:query')")
    public UserInfoVo getUserInfo(@PathVariable(value = "userId", required = false) Long userId) {
        UserInfoVo userInfoVo = new UserInfoVo();
        userService.checkUserDataScope(userId);
        if (StringUtils.isNotNull(userId)) {
            UserEntity userEntity = userService.selectUserById(userId);
            userService.checkUserAllowed(userEntity);
            userInfoVo.setUser(userEntity);
            userInfoVo.setPostIds(postService.selectPostListByUserId(userId));
            userInfoVo.setRoleIds(roleService.selectRoleListByUserId(userId));
        }
        /*封装所有角色列表信息*/
        userInfoVo.setRoleList(roleService.selectAllRole());
        /*封装所有岗位列表信息*/
        userInfoVo.setPostList(postService.selectAllPost());
        return userInfoVo;
    }

    /**
     * 修改用户
     *
     * @param userEntity 用户信息
     * @return 结果
     */
    @PutMapping("/updateUser")
    @Log(title = "用户管理", businessType = BusinessType.UPDATE)
    @PreAuthorize("@security.isPermission('permissions:user:edit')")
    public AjaxResult updateUser(@Validated @RequestBody UserEntity userEntity) {
        userService.checkUserAllowed(userEntity);
        userService.checkUserDataScope(userEntity.getUserId());
        if (UserConstant.NOT_UNIQUE.equals(userService.checkUserNameUnique(userEntity))) {
            return error("修改用户'" + userEntity.getUserName() + "'失败，登录账号已存在");
        } else if (StringUtils.isNotEmpty(userEntity.getPhoneNumber())
                && UserConstant.NOT_UNIQUE.equals(userService.checkPhoneUnique(userEntity))) {
            return error("修改用户'" + userEntity.getUserName() + "'失败，手机号码已存在");
        } else if (StringUtils.isNotEmpty(userEntity.getEmail())
                && UserConstant.NOT_UNIQUE.equals(userService.checkEmailUnique(userEntity))) {
            return error("修改用户'" + userEntity.getUserName() + "'失败，邮箱账号已存在");
        }
        return toAjax(userService.updateUser(userEntity));
    }

    /**
     * 修改用户状态
     *
     * @param userEntity 用户信息
     * @return 结果
     */
    @PutMapping("/changeStatus")
    @Log(title = "用户管理", businessType = BusinessType.UPDATE)
    @PreAuthorize("@security.isPermission('permissions:user:edit')")
    public AjaxResult changeStatus(@RequestBody UserEntity userEntity) {
        userService.checkUserAllowed(userEntity);
        userService.checkUserDataScope(userEntity.getUserId());
        return toAjax(userService.changeStatus(userEntity));
    }

    /**
     * 根据用户ID删除用户信息
     *
     * @param userIds 需要删除的用户ID
     * @return 结果
     */
    @DeleteMapping("/deleteUser/{userIds}")
    @Log(title = "用户管理", businessType = BusinessType.DELETE)
    @PreAuthorize("@security.isPermission('permissions:user:remove')")
    public AjaxResult remove(@PathVariable Long[] userIds) {
        return toAjax(userService.deleteUserByIds(userIds));
    }

    /**
     * 重置用户密码
     *
     * @param userEntity 用户信息
     * @return 结果
     */
    @PutMapping("/resetPwd")
    @Log(title = "用户管理", businessType = BusinessType.UPDATE)
    @PreAuthorize("@security.isPermission('permissions:user:resetPwd')")
    public AjaxResult resetPwd(@RequestBody UserEntity userEntity) {
        userService.checkUserAllowed(userEntity);
        userService.checkUserDataScope(userEntity.getUserId());
        return toAjax(userService.restPossWord(userEntity));

    }

    /**
     * 根据用户ID获角色列表
     *
     * @param userId 用户ID
     * @return 结果
     */
    @GetMapping("/authRole/{userId}")
    @PreAuthorize("@security.isPermission('permissions:user:query')")
    public AjaxResult authRole(@PathVariable("userId") Long userId) {

        AjaxResult ajaxResult = new AjaxResult();
        UserEntity userEntity = userService.selectUserById(userId);
        List<RoleEntity> roles = userService.selectRoleByUserId(userId);
        List<RoleEntity> roleEntityList = SecurityUtils.isAdmin(SecurityUtils.getUserIdentity()) ?
                roles : roles.stream().filter(r -> !r.getIdentity().equals("0")).collect(Collectors.toList());
        ajaxResult.put("userEntity", userEntity);
        ajaxResult.put("roleList", roleEntityList);
        return ajaxResult;
    }

    /**
     * 用户授权角色
     *
     * @param userId  用户ID
     * @param roleIds 角色组
     * @return 结果
     */
    @PutMapping("/authRole")
    @Log(title = "用户管理", businessType = BusinessType.GRANT)
    @PreAuthorize("@security.isPermission('permissions:user:edit')")
    public AjaxResult insertAuthRole(Long userId, Long[] roleIds) {
        userService.checkUserAllowed(userService.selectUserById(userId));
        userService.checkUserDataScope(userId);
        userService.insertUserAuth(userId, roleIds);
        return success();
    }

    /**
     * 获取用户管理页面部门树列表
     *
     * @param deptEntity
     * @return 部门树列表
     */
    @GetMapping("/deptTreeSelect")
    @PreAuthorize("@security.isPermission('permissions:user:list')")
    public AjaxResult deptTreeSelect(DeptEntity deptEntity) {
        return AjaxResult.success(deptService.selectDeptTreeList(deptEntity));
    }
}
